﻿using System.Text.Json;
using System.Text.Json.Serialization;

namespace SBlogCore.Common.CacheExtend.RedisCacheExtension
{
    public class SBlogRedisCache : ISBlogCoreCache
    {
        public SBlogRedisCache()
        {
            string configuration = AppSetting.ReadAppSettings("Cache:Redis:Configuration");
            var csRedis = new CSRedis.CSRedisClient(configuration);
            RedisHelper.Initialization(csRedis);
        }
        private JsonSerializerOptions Options => new()
        {
            ReferenceHandler = ReferenceHandler.IgnoreCycles,
            WriteIndented = true
        };
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public  TResult Get<TResult>(string key)    
        {
           return RedisHelper.Get<TResult>(key);
        }
        /// <summary>
        /// 存储数据
        /// </summary>
        /// <param name="key"></param>  
        /// <param name="value"></param>
        /// <returns></returns>
        public  void Create<TResult>(string key, TResult value)
        {
            var result= JsonSerializer.Serialize(value, Options);
            RedisHelper.Set(key, result);
        }
        /// <summary>
        /// 存储数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public  void Create<TResult>(string key, TResult value, long timeout)
        {
            var result = JsonSerializer.Serialize(value, Options);
            RedisHelper.Set(key, result, TimeSpan.FromSeconds(timeout));
        }
        /// <summary>
        /// 获取或创建
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <param name="valueFactory"></param>
        /// <returns></returns>
        public TResult? GetOrCreate<TResult>(string key, Func<TResult>? valueFactory)
        {
            TResult result=default;
            //Key不存在
            if (!RedisHelper.Exists(key))
            {
                if (valueFactory != null)
                {
                    result = valueFactory.Invoke();
                    Create(key, result);
                }
            }
            else
            {
                result = Get<TResult>(key);
            }
            return result;
        }

        /// <summary>
        /// 获取或创建
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <param name="valueFactory"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public TResult? GetOrCreate<TResult>(string key, Func<TResult>? valueFactory, long timeout)
        {
            TResult result=default;
            //Key不存在
            if (!RedisHelper.Exists(key))
            {
                if (valueFactory != null)
                {
                    result = valueFactory.Invoke();
                    Create(key, result, timeout);
                }
            }
            else
            {
                result = Get<TResult>(key);
            }
            return result;
        }
        /// <summary>
        /// 异步获取
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<TResult?> GetAsync<TResult>(string key)
        {
            return await RedisHelper.GetAsync<TResult>(key);
        }
        /// <summary>
        /// 异步存储数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task CreateAsync<TResult>(string key, TResult value)
        {
            var result = JsonSerializer.Serialize(value, Options);
            await RedisHelper.SetAsync(key, result);
        }
        /// <summary>
        /// 异步存储数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public  async Task CreateAsync<TResult>(string key, TResult value, long timeout)
        {
            try
            {
                var result = JsonSerializer.Serialize(value, Options);
                await RedisHelper.SetAsync(key, result, TimeSpan.FromSeconds(timeout));
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            
        }
        /// <summary>
        /// 获取或者创建缓存
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <param name="valueFactory"></param>
        /// <returns></returns>
        public async Task<TResult?> GetOrCreateAsync<TResult>(string key, Func<Task<TResult>>? valueFactory)
        {
            TResult result=default;
            //Key不存在
            if (!await RedisHelper.ExistsAsync(key))    
            {
                if (valueFactory != null)
                {
                    result =await valueFactory.Invoke();
                    await CreateAsync(key, result);
                }
            }
            else
            {
                result = await GetAsync<TResult>(key);
            }
            return result;
        }

        /// <summary>
        /// 获取或者创建缓存
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <param name="valueFactory"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public async Task<TResult?> GetOrCreateAsync<TResult>(string key, Func<Task<TResult>>? valueFactory, long timeout)
        {
            TResult result=default;
            //Key不存在
            if (!await RedisHelper.ExistsAsync(key))
            {
                if (valueFactory != null)
                {
                    result = await valueFactory.Invoke();
                    await CreateAsync(key, result, timeout);
                }
            }
            else
            {
                result = await GetAsync<TResult>(key);
            }
            return result;
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="cacheKey"></param>
        public  void Remove(params string[] cacheKey)
        {
             RedisHelper.Del(cacheKey);
        }
        /// <summary>
        /// 异步删除
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        public  async Task RemoveAsync(params string[] cacheKey)
        {
           await RedisHelper.DelAsync(cacheKey);
        }
        /// <summary>
        /// 根据分区删除
        /// </summary>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public async Task<long> RemoveByPatternAsync(string pattern)
        {
            if (string.IsNullOrEmpty(pattern))
                return default;
            var keys = (await RedisHelper.KeysAsync(pattern));
            if (keys is {Length: > 0})
            {
                return await RedisHelper.DelAsync(keys);
            }
            return default;
        }
    }
}
